package com.songshuang.myutilsboot.stlf.api;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.songshuang.myutilsboot.stlf.core.AnnPredictor;
import com.songshuang.myutilsboot.stlf.core.ReportWriter;
import com.songshuang.myutilsboot.stlf.io.Jsons;
import com.songshuang.myutilsboot.stlf.io.ModelFiles;
import com.songshuang.myutilsboot.stlf.model.Models;
import com.songshuang.myutilsboot.stlf.util.LogWriter;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public final class StlfApi {
    private StlfApi() {}

    // 与C++一致：返回值为 char*（这里用 String），入参为 json 字符串
    public static String stlf_annmodel_version(String cfg) {
        try {
            Models.InputParameter ip = Jsons.parseAnnOrLrOrExpsCfg(cfg);
            LogWriter.write("获取模型版本号列表入参如下：", cfg);
            // 扫描 ./dataFile/annmodel/ 目录，按经纬度与可选时间范围过滤
            double lng = ip.global_rc == null ? 0 : ip.global_rc.pv_nlng;
            double lat = ip.global_rc == null ? 0 : ip.global_rc.pv_nlat;
            String st = null; String et = null;
            if (ip instanceof Models.InputParameter) {
                // 兼容：如果顶层JSON包含 start_time/end_time（yyyy-MM-dd 或 yyyyMMdd），按范围筛选
                // 当前 Models 未建字段，这里保留占位（将来如模型扩展，可从解析对象读取）
            }
            List<String> versions = ModelFiles.scanModelVersions(lng, lat, st, et);
            String data = Jsons.serializeModelVersions(
                    ip.global_rc == null ? 0 : ip.global_rc.pv_nlng,
                    ip.global_rc == null ? 0 : ip.global_rc.pv_nlat,
                    versions
            );
            LogWriter.write("获取模型版本号列表结果如下:", data);
            return Jsons.wrapResult("200", "获取模型版本号列表成功！！！", data);
        } catch (Exception e) {
            return Jsons.wrapResult("201", "获取模型版本号列表传入的参数有误，请校验后重试！！！", "");
        }
    }

    public static String stlf_annpv_forecast(String cfg) {
        LogWriter.ensureDirs();
        Models.InputParameter ip;
        try {
            ip = Jsons.parseAnnOrLrOrExpsCfg(cfg);
        } catch (JsonProcessingException e) {
            return Jsons.wrapResult("201", "神经网络算法预测功率传入的参数有误 ,请校验后重试！！！", "");
        }
        if (ip.global_rc != null && ip.global_rc.debug_flag == 1) {
            LogWriter.write("神经网络算法功率预测入参如下：", cfg);
        }
        
        // 执行ANN预测算法
        Models.ForecastInfo fi = new Models.ForecastInfo();
        fi.start_time = nowDateTime();
        fi.end_time = nowDateTime();
        fi.model_version = ip.global_rc == null ? null : ip.global_rc.pv_model_version;
        
        // 执行ANN预测计算
        try {
            boolean ok = AnnPredictor.predict(ip, fi);
            if (!ok) {
                return Jsons.wrapResult("202", "神经网络算法预测功率失败！！！（模型缺失或配置错误）", "");
            }
        } catch (Exception e) {
            LogWriter.write("ANN预测计算失败", e.getMessage());
            return Jsons.wrapResult("202", "神经网络算法预测功率计算失败！！！", "");
        }
        // 写.res/.dat（case 名优先使用 model_version，否则回退默认）
        try {
            String caseStr = (ip.global_rc != null && ip.global_rc.pv_model_version != null) ? ip.global_rc.pv_model_version : "stlf_pv02";
            ReportWriter.writeResAndDat(caseStr, fi);
        } catch (Exception ignored) {}
        
        String data = Jsons.serializeForecast(fi);
        if (ip.global_rc != null && ip.global_rc.debug_flag == 1) {
            LogWriter.write("神经网络算法功率预测结果如下:", data);
        }
        return Jsons.wrapResult("200", "神经网络算法预测功率成功！！！", data);
    }

    public static String stlf_lrpv_forecast(String cfg) {
        LogWriter.ensureDirs();
        Models.InputParameter ip;
        try {
            ip = Jsons.parseAnnOrLrOrExpsCfg(cfg);
        } catch (JsonProcessingException e) {
            return Jsons.wrapResult("201", "线性回归分析预测功率传入的参数有误 ,请校验后重试！！！", "");
        }
        if (ip.global_rc != null && ip.global_rc.debug_flag == 1) {
            LogWriter.write("线性回归分析功率预测入参如下：", cfg);
        }
        Models.ForecastInfo fi = new Models.ForecastInfo();
        fi.start_time = nowDateTime();
        fi.end_time = nowDateTime();
        boolean ok = com.songshuang.myutilsboot.stlf.core.LrPredictor.predict(ip, fi);
        if (!ok) return Jsons.wrapResult("202", "线性回归分析预测功率失败！！！", "");
        String data = Jsons.serializeForecast(fi);
        if (ip.global_rc != null && ip.global_rc.debug_flag == 1) {
            LogWriter.write("线性回归分析功率预测结果如下：", data);
        }
        return Jsons.wrapResult("200", "线性回归分析预测功率成功！！！", data);
    }

    public static String stlf_exps_forecast(String cfg) {
        LogWriter.ensureDirs();
        Models.InputParameter ip;
        try {
            ip = Jsons.parseAnnOrLrOrExpsCfg(cfg);
        } catch (JsonProcessingException e) {
            return Jsons.wrapResult("201", "指数平滑法负荷预测传入的参数有误 ,请校验后重试！！！", "");
        }
        if (ip.global_rc != null && ip.global_rc.debug_flag == 1) {
            LogWriter.write("指数平滑法负荷预测入参如下：", cfg);
        }
        Models.ForecastInfo fi = new Models.ForecastInfo();
        fi.start_time = nowDateTime();
        fi.end_time = nowDateTime();
        boolean ok = com.songshuang.myutilsboot.stlf.core.ExpsPredictor.predict(ip, fi);
        if (!ok) return Jsons.wrapResult("202", "指数平滑法负荷预测失败！！！", "");
        String data = Jsons.serializeForecast(fi);
        if (ip.global_rc != null && ip.global_rc.debug_flag == 1) {
            LogWriter.write("指数平滑法负荷预测结果如下：", data);
        }
        return Jsons.wrapResult("200", "指数平滑法负荷预测成功！！！", data);
    }

    private static String nowDateTime() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }
}


